package com.zgkxzx.android.androidtest;


import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.support.v4.app.NotificationManagerCompat;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.animation.AlphaAnimation;
import android.widget.TextView;
import android.widget.Toast;

import com.zgkxzx.android.rx.Action1;
import com.zgkxzx.android.rx.Func1;
import com.zgkxzx.android.rx.Observable;
import com.zgkxzx.android.rx.OnSubscribe;
import com.zgkxzx.android.rx.Subscriber;
import com.zgkxzx.android.rx.schedule.Schedulers;
import com.zgkxzx.android.greendao.*;

import com.zgkxzx.java.mutilThread.Account;
import com.zgkxzx.java.mutilThread.BankThread;
import com.zgkxzx.java.mutilThread.CountDownLatchTest.ThreadCount1;
import com.zgkxzx.java.mutilThread.CountDownLatchTest.ThreadCount2;
import com.zgkxzx.算法.排序.Sort;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MainActivity extends Activity {
    private final static String TAG = MainActivity.class.getSimpleName();
    private TextView tvTitle;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Window window = getWindow();
        tvTitle = (TextView) findViewById(R.id.tv_title);


        //开始动画
        //tvTitle.startAnimation(AnimationUtils.loadAnimation(this,R.drawable.drawbackbitmap));
        tvTitle.setText("开始动画。。。。");

        /*ObjectAnimator mAnimator = ObjectAnimator.ofFloat(tvTitle, "translationY", 300);
        mAnimator.setDuration(3000);
        mAnimator.start();*/

        ObjectAnimator mAnimator1 = ObjectAnimator.ofFloat(tvTitle, "translationY", 300);
        ObjectAnimator mAnimator2 = ObjectAnimator.ofFloat(tvTitle, "scaleX", 1f, 0f, 1f);
        ObjectAnimator mAnimator3 = ObjectAnimator.ofFloat(tvTitle, "scaleY", 1f, 0f, 1f);
        AnimatorSet mSet = new AnimatorSet();
        mSet.setDuration(3000);
        mSet.playTogether(mAnimator1, mAnimator2, mAnimator3);
        mSet.start();


        AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
        tvTitle.startAnimation(alphaAnimation);


        ObjectAnimator objectAnimator = new ObjectAnimator();

//        fromTest();
//        justTest();
//        mapTest();
//        flatMapTest();
//        flatMapObservable();
//        filterTest();
        sort();
        //NasisisterTest();

       /* try {
            threadLocalTest();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/

        //mutilThreadTest();
        //greenDaoTest();


        Map<Integer, String> map = new HashMap<>();

        map.put(1, "a");
        map.put(2, "af");
        map.put(3, "as");
        map.put(4, "ad");

        Set<Integer> strings = map.keySet();

        Set<Map.Entry<Integer, String>> entries = map.entrySet();

        List<Map.Entry<Integer, String>> entrieList = new ArrayList<>(entries);

        Collections.sort(entrieList, new Comparator<Map.Entry<Integer, String>>() {
            @Override
            public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
                return o1.getKey() - o2.getKey();
            }
        });

        for (Map.Entry<Integer, String> entrie : entrieList) {
            Log.d(TAG, " entrie " + entrie);
        }

        Iterator<Map.Entry<Integer, String>> iterator =
                entries.iterator();

        while (iterator.hasNext()) {
            Map.Entry<Integer, String> next = iterator.next();
            Log.d(TAG, " next " + next);
        }


        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("com.zgkxzx.broadcast");
        registerReceiver(broadcastReceiver, intentFilter);


        sendBroadcast(new Intent().setAction("com.zgkxzx.broadcast"));

        contentProviderTest();

        //classLoader
//        ClassLoader loader = MainActivity.class.getClassLoader();
//        while (loader != null) {
//            System.out.println(loader.toString());
//            loader = loader.getParent();
//        }
//
//        testNet();


//        if (!isNotificationListenerServiceEnabled(this))
//            startActivity(new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS));


        Intent intent = new Intent(this, LocalService.class);
        startService(intent);

        handlerTest();

        handlerThreadTest();


        EventBus.getDefault().register(this);
    }

    private static boolean isNotificationListenerServiceEnabled(Context context) {
        Set<String> packageNames = NotificationManagerCompat.getEnabledListenerPackages(context);
        if (packageNames.contains(context.getPackageName())) {
            return true;
        }
        return false;
    }

    //网络测试
    private void testNet() {
        try {
            URL url = new URL("");
            InputStream inputStream = url.openStream();

            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] aBytes = new byte[1024];
            int len = 0;
            while ((len = inputStream.read(aBytes)) != -1) {
                byteArrayOutputStream.write(aBytes, 0, len);
            }

            byte[] bytes = byteArrayOutputStream.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //Handler测试
    Handler childHandler;

    private void handlerTest() {


        new Thread(new Runnable() {

            @Override
            public void run() {
                String msg;
                Looper.prepare();

                childHandler = new Handler() {
                    @Override
                    public void handleMessage(Message msg) {
                        super.handleMessage(msg);

                        Log.d(TAG, "这个消息是从-->>" + msg.obj + "过来的，在" + "btn的子线程当中" + "中执行的");

                    }

                };
                Looper.loop();//开始轮循

            }
        }).start();

        new Thread(new Runnable() {

            @Override
            public void run() {
                Looper loop = Looper.myLooper();
                Message msg = childHandler.obtainMessage();
                msg.obj = "btn2当中子线程";

                childHandler.sendMessage(msg);
            }
        }).start();


    }

    //////
    HandlerThread mHandlerThread = new HandlerThread("MyThread");
    Handler mHandler;

    private void handlerThreadTest() {
        mHandlerThread.start();


        long id = Thread.currentThread().getId();
        Log.d(TAG, "Main ThreadName:" + Thread.currentThread().getName() + "  ThreadId:" + id);

        new Thread(new Runnable() {
            @Override
            public void run() {
                mHandler = new Handler(mHandlerThread.getLooper());//
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        long id = Thread.currentThread().getId();
                        Log.d(TAG, "Thread ThreadName:" + Thread.currentThread().getName() + "  ThreadId:" + id);
                        Toast.makeText(MainActivity.this, "nihao", Toast.LENGTH_SHORT).show();
                        tvTitle.setText("ThreadName。。。。");
                    }
                });

            }
        }).start();


    }

    /////////////////////////////////////
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void Event(MsgEvent msgEvent) {
        Log.d(TAG, "====>" + msgEvent);
    }


    BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            String name = Thread.currentThread().getName();
            Log.d(TAG, " broadcastReceiver onReceive..." + name);
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(18000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    String name = Thread.currentThread().getName();
                    Log.d(TAG, " broadcastReceiver onReceive over " + name);
                }
            }).start();
        }
    };


    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(broadcastReceiver);
        EventBus.getDefault().unregister(this);
    }


    private void contentProviderTest() {
        // getContentResolver()

        getContentResolver().registerContentObserver(Uri.parse("content://com.zgkxzx.android.providertest.StudentContentProvider"), true, new BookContentObserver(new Handler()));
    }

    class BookContentObserver extends ContentObserver {


        public BookContentObserver(Handler handler) {
            super(handler);

            Log.d(TAG, " BookContentObserver onCreate------");
        }

        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            Log.d(TAG, " BookContentObserver onChange------");

        }
    }

    public void testContentEvent(View view) {
        Log.d(TAG, " testContentEvent------");

        startActivity(new Intent(this, SecondActivity.class));


        //LayoutInflater from = LayoutInflater.from(this);

        //SecondActivity.LineItemView2 lineItemView2 = new SecondActivity().new LineItemView2(this);


    }


    //botton事件
    public void test2ContentEvent() {
        Log.d(TAG, " testContentEvent------");

        Uri bookUri = Uri.parse("content://com.zgkxzx.android.providertest.StudentContentProvider/book");

        ContentResolver contentResolver = getContentResolver();

        ContentValues contentValues = new ContentValues();
        contentValues.put("bookName", "叫什么名字好呢");
        contentResolver.insert(bookUri, contentValues);

        contentValues.put("bookName", "C语言程序设计");
        contentResolver.insert(bookUri, contentValues);


        Cursor bookCursor = contentResolver.query(bookUri, new String[]{"_id", "bookName"}, null, null, null);
        if (bookCursor != null) {
            while (bookCursor.moveToNext()) {
                Log.e(TAG, "ID:" + bookCursor.getInt(bookCursor.getColumnIndex("_id"))
                        + "  BookName:" + bookCursor.getString(bookCursor.getColumnIndex("bookName")));
            }
            bookCursor.close();
        }




        /*while (cursor.moveToNext()) {
            String name = cursor.getString(cursor
                    .getColumnIndex("name"));
            String package_name = cursor.getString(cursor
                    .getColumnIndex("package_name"));
            String activity_name = cursor.getString(cursor
                    .getColumnIndex("activity_name"));
            int id = cursor.getInt(cursor.getColumnIndex("id"));

            Log.i(TAG, id + ":" + name + ":" + package_name
                    + ":" + activity_name);
            Log.i(TAG, "=================================");
        }*/

    }

    private void greenDaoTest() {
        Shop shop = new Shop();
        shop.setAddress("shenZhen");
        shop.setImage_url("www.zhenshen.com");
        shop.setName("haoc");
        shop.setPrice("12.2");

        LoveDao.getInstance().insertShop(shop);

        Shop shop1 = new Shop();
        shop1.setAddress("guangzhou");
        shop1.setImage_url("www.guangzhou.com");
        shop1.setName("chi");
        shop1.setPrice("15.2");

        LoveDao.getInstance().insertShop(shop1);

        shop1.setAddress("Chaind");

        LoveDao.getInstance().updateShop(shop1);


        List<Shop> shops = LoveDao.getInstance().getShops();

        for (Shop s : shops) {
            Log.d(TAG, "数据库的数据 。。" + s);
        }


    }


    private void threadLocalTest() throws InterruptedException {
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        for (int i = 0; i < 15; i++) {
            //newCachedThreadPool.execute(new MyThread());
        }


//        MyRunnable myRunnable = new MyRunnable();
//        new Thread(myRunnable,"1-Runnable").start();
//        new Thread(myRunnable,"2-Runnable").start();
//        new Thread(myRunnable,"3-Runnable").start();
//        new Thread(myRunnable,"4-Runnable").start();
//
//        MyThread myThread = new MyThread();
//        new Thread(myThread,"1-Thread").start();
//        new Thread(myThread,"2-Thread").start();
//        new Thread(myThread,"3-Thread").start();
//        new Thread(myThread,"4-Thread").start();

        //join测试
       /* MyThread myThread1 = new MyThread("zx1");
        MyThread myThread2 = new MyThread("zx22");
        myThread1.start();

        myThread1.join();

        myThread2.start();

        myThread2.join();
        System.out.println("Test over.....");*/

        //wait 和 notify

        //EventModel eventModel = new EventModel();
        /*EventLockModel eventModel = new EventLockModel();

        Producer producer = new Producer(eventModel);

        Consumer consumer = new Consumer(eventModel);

        new Thread(producer).start();

        new Thread(consumer).start();*/

        //CountDownLatch
        CountDownLatch countDownLatch = new CountDownLatch(2);
        Exchanger<String> stringExchanger = new Exchanger<>();
        new Thread(new ThreadCount1(countDownLatch, stringExchanger)).start();
        new Thread(new ThreadCount2(countDownLatch, stringExchanger)).start();
        System.out.println("等待子线程处理");
        countDownLatch.await();
        System.out.println("合并数据");
        //CyclicBarrier
//        CyclicBarrier cyclicBarrier = new CyclicBarrier(4);
//        for (int i = 0; i < 4; i++)
//            new CircleThread(cyclicBarrier).start();
//        System.out.println("执行完成.....");


    }

    class MyRunnable implements Runnable {
        private int ticket = 10;
        private String name;

        @Override
        public void run() {
            // for(int i =0;i<500;i++)
            {
                if (this.ticket > 0) {
                    System.out.println(Thread.currentThread().getName() + "卖票---->" + (this.ticket--));
                }
            }
        }
    }

    class MyThread extends Thread {

        private int ticket = 10;
        private String name;

        public MyThread(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                if (this.ticket > 0) {
                    System.out.println(name + " -- " + Thread.currentThread().getName() + "卖票---->" + (this.ticket--));
                }

                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    private void mutilThreadTest() {
        Account account = new Account(0);
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 20; i++) {
            executorService.execute(new BankThread(account));
        }

        executorService.shutdown();

        while (!executorService.isTerminated()) {

        }

        Log.d(TAG, " 存款余额 " + account.getBalance());

        new Thread(new Runnable() {
            @Override
            public void run() {

            }
        }).start();
    }


    /**
     * 水仙数 1000以内的
     */
    private void NasisisterTest() {

//        for (int i = 0; i < 1000; i++) {
//            int bai = i / 100;
//            int shi = i / 10 % 10;
//            int ge = i % 10;
//            if (Math.pow(bai, 3) + Math.pow(shi, 3) + Math.pow(ge, 3) == i) {
//                Log.d(TAG, "水仙数 --> " + i);
//            }
//        }
        NasisiterCalc(10000);//4000000000L);
    }

    private void NasisiterCalc(long num) {
        for (long i = 0; i < num; i++) {
            Log.d(TAG, "i= " + i);
            if (i == getPerNum(i)) {
                Log.d(TAG, "水仙数 --> " + i);
            }
        }
    }

    private long getPerNum(long num) {
        long sum = 0;
        while (num > 0) {
            long calNum = num % 10;
            sum += Math.pow(calNum, 3);
            num = num / 10;
        }

        return sum;
    }


    /**
     * 排序
     */
    public void sort() {
        int[] dat = {1, 56, 32, 75, 2, 59, 3, 642, 33, 178, 2, 1, 2, 3, 2, 1, 23, 5, 453, 23, 23
        };
        long l = System.currentTimeMillis();
        //int [] dat = {1,2,3};
        Log.d(TAG, " 排序前 " + Arrays.toString(dat));
        Sort.bubbleSort(dat);
        Log.d(TAG, " 排序后 " + Arrays.toString(dat) + "\n SystemTime " + (System.currentTimeMillis() - l));

        int[] dat1 = {1, 56, 32, 75, 2, 59, 3, 642, 33, 178, 2, 1, 2, 3, 2, 1, 23, 5, 453, 23, 23
        };
        //int [] dat = {1,2,3};
        long l1 = System.currentTimeMillis();
        Log.d(TAG, " 排序前 " + Arrays.toString(dat1));
        Sort.insertSort(dat1);
        Log.d(TAG, " 排序后 " + Arrays.toString(dat1) + "\n SystemTime " + (System.currentTimeMillis() - l1));

    }


    public void fromTest() {
        Log.d(TAG, "--------------------- fromTest ----------------");
        final String strs[] = {"zfg", "fads", "fasd", "fddd", "dd22"};
        Observable.create(new OnSubscribe<String>() {

            @Override
            public void call(Subscriber<String> subscriber) {
                String name = Thread.currentThread().getName();
                Log.d(TAG, " Observable Thread name " + name);
                for (String str : strs)
                    subscriber.onNext(str);
            }
        })
                .observeOn(Schedulers.io())
                .subscribeOn(Schedulers.io())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.d(TAG, " call " + s);
                        String name = Thread.currentThread().getName();
                        Log.d(TAG, " subscribe name " + name);
                    }
                });
    }

    public void justTest() {
        Log.d(TAG, "--------------------- justTest ----------------");
        Observable.just("zfg", "fads", "fasd", "fddd", "dd22")
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onCompleted() {
                        Log.d(TAG, " onCompleted ");
                    }

                    @Override
                    public void onNext(String o) {
                        Log.d(TAG, " onNext " + o);
                    }
                });
    }

    public void mapTest() {
        Log.d(TAG, "--------------------- mapTest ----------------");
        Observable.just("zfg", "fads", "fasd", "fddd", "dd22")
                .map(new Func1<String, String>() {
                    @Override
                    public String call(String o) {
                        Log.d(TAG, " call " + o);
                        return o + "123";
                    }
                }).
                map(new Func1<String, String>() {
                    @Override
                    public String call(String o) {
                        Log.d(TAG, " call2 " + o);
                        return o + "888";
                    }
                }).
                subscribe(new Subscriber<String>() {
                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onCompleted() {
                        Log.d(TAG, " onCompleted ");
                    }

                    @Override
                    public void onNext(String o) {
                        Log.d(TAG, " onNext " + o);
                    }
                });
    }

    public void flatMapTest() {
        Log.d(TAG, "--------------------- flatMapTest ----------------");
        Observable.just("zfg", "fads", "fasd", "fddd", "dd22")
                .flatMap(new Func1<String, String>() {
                    @Override
                    public String call(String o) {
                        Log.d(TAG, " call " + o);
                        return o + "123";
                    }
                }).
                subscribe(new Subscriber<String>() {
                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onCompleted() {
                        Log.d(TAG, " onCompleted ");
                    }

                    @Override
                    public void onNext(String o) {
                        Log.d(TAG, " onNext " + o);
                    }
                });
    }

    /*.flatMap(new Func1<File, Observable<File>>() {
     @Override
     public Observable<File> call(File file) {
         return Observable.from(file.listFiles());
     }
 })*/
    public void flatMapObservable() {
        Log.d(TAG, "--------------------- flatMapObservable ----------------");
        File file[] = {Environment.getExternalStorageDirectory(), Environment.getExternalStorageDirectory()};
        Observable.from(file)
                .flatMap(new Func1<File, Observable<File>>() {
                    @Override
                    public Observable<File> call(File file) {
                        return Observable.from(file.listFiles());
                    }
                }).subscribe(new Subscriber<Observable<File>>() {
            @Override
            public void onError(Throwable e) {
                Log.d(TAG, " Throwable " + e);
            }

            @Override
            public void onCompleted() {
                Log.d(TAG, " onCompleted ");
            }

            @Override
            public void onNext(Observable<File> o) {
                Log.d(TAG, " onNext --> o " + o);
                o.subscribe(new Subscriber<File>() {
                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onNext(File file) {
                        Log.d(TAG, " onNext --> " + file.getAbsolutePath());
                    }
                });

            }
        });
    }

    public void filterTest() {
        Log.d(TAG, "--------------------- filterTest ----------------");
        String strs[] = {"zfg.png", "fads.jpg", "fasd.bmp", "fddd.png", "dd22.png"};
        Observable.from(strs).
                filter(new Func1<String, Boolean>() {
                    @Override
                    public Boolean call(String fileName) {
                        return fileName.endsWith(".png");
                    }
                })


                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onCompleted() {
                        Log.d(TAG, " onCompleted ");
                    }

                    @Override
                    public void onNext(String o) {
                        Log.d(TAG, " onNext " + o);
                    }
                });
    }

    private void subscrbeTest() {
        Log.d(TAG, "--------------------- subscrbeTest ----------------");
        Observable.create(new OnSubscribe<String>() {
            @Override
            public void call(Subscriber<String> subscriber) {
                subscriber.onNext("zzzxxxx");
            }
        }).subscribe(new Subscriber<String>() {
            @Override
            public void onError(Throwable e) {
                Log.d(TAG, " onError " + e);
            }

            @Override
            public void onCompleted() {
                Log.d(TAG, " onCompleted ");
            }

            @Override
            public void onNext(String o) {
                Log.d(TAG, " onNext " + o);
            }
        });
    }


}
